import axios from 'axios';
import { ElMessage } from 'element-plus';
import config from '../config';
import router from '../router';

const TOKEN_INVALID = 'Token错误,请重新登录';
const NETWORK_ERROR = '网络异常,请稍后重试';
// 创建axios实例对象，添加全局配置
const instance = axios.create({
  baseURL: config.baseApi,
  timeout: 8000,
});

// 请求拦截器,处理token,时间参数的格式转化等
instance.interceptors.request.use((req) => {
  const { headers } = req;
  // TODO 模拟Authorization Token
  if (!headers.Authorization) headers.Authorization = 'Bearer Jack';
  return req;
});

// 响应拦截器,对返回值的错误处理
instance.interceptors.response.use((res) => {
  // 假设返回的数据结构为 code, data, msg
  const { code, data, msg } = res.data;
  if (code === 200) {
    return data;
  } if (code === 40001) { // 登录过期或失效(token错误)
    ElMessage.error(TOKEN_INVALID);
    setTimeout(() => {
      router.push('/login');
    }, 15000);
    return Promise.reject(TOKEN_INVALID);
  }
  ElMessage.error(msg || NETWORK_ERROR);
  return Promise.reject(msg || NETWORK_ERROR);
});

/**
 * axios核心处理函数,对get请求的params重新封装,请求地址的进一步确认等...
 * @param {*} options 请求参数
 * @returns axios实例对象
 */
function request(options) {
  // 封装get请求的参数为params
  options.method = options.method || 'get';
  if (options.method.toLowerCase() === 'get') {
    options.params = options.data;
  }

  // 确认prod环境下的baseURL,防止使用mockApi
  if (config.env === 'prod') {
    instance.defaults.baseURL = config.baseApi;
  } else { // 反之亦然
    instance.defaults.baseURL = config.mock ? config.mockApi : config.baseApi;
  }
  return instance(options);
}

// 第二种调用方式
['get', 'post', 'delete', 'put', 'patch'].forEach((item) => {
  request[item] = (url, data, options) => request({
    url, data, options, method: item,
  });
});
export default request;
